iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 11
0
Mobile Development

老姐好像要用 Kotlin 寫專案,能撐30天嗎?系列 第 11

內部進化的第十一天:動起來吧,資料庫!塞資料的時機到了!

  • 分享至 

  • xImage
  •  

今天要開始往資料庫塞資料,再也不能忽視之前那個連線失敗問題。

https://ithelp.ithome.com.tw/upload/images/20200917/20129197KqWr0OkCI5.png

其實是因為我連線模式忘了選擇,更正確的說,我當初沒找到選擇的地方,所以被預設成 Remote 了。

https://ithelp.ithome.com.tw/upload/images/20200920/20129197iZ2BhlRMAf.png

https://ithelp.ithome.com.tw/upload/images/20200920/20129197drrmSRKhPq.png

打開資料庫設定頁面後,點擊 Connection type 旁邊的藍色文字會看到可以選的四個選項。
和 H2 官網 http://www.h2database.com/html/features.html 不同,官網是把連線模式和儲存資料做組合, IDE Intellij idea 簡化了選項。

IDE選項 和官網比對
remote Server 連線(帳密登入) + persistent 儲存資料
in-memory Embedded 連線 + in-memory 儲存資料
Embedded Embedded 連線 + persistent 儲存資料
URL only Server 連線 + persistent 儲存資料

因為開發中資料庫欄位常需要變動,所以選擇 in-memory ,這樣每次連線結束都會清掉資料庫。

https://ithelp.ithome.com.tw/upload/images/20200920/20129197FLs4kbkOBi.png

接著為了在程式中執行 jdbc 連線,所以要在 build.gradle 新增 Library 。

    implementation "org.jetbrains.exposed:exposed-jdbc:$exposed_version"

這樣就可以建立 Topics table 了!
連線資訊複製資料庫設定頁面的地方, mem 就是 in-memory 的意思。

    Database.connect("jdbc:h2:mem:default", driver = "org.h2.Driver")
    transaction {
        SchemaUtils.create(Topics)
    }

接下來我把亂數資料放進資料庫,因為每個 transaction 區塊是一個整體。如果其中一行壞了,整個 transaction 都會回復成執行前的樣子,所以我把它和建立 table 的程式碼分開。

    transaction {
        for (i in 0..10) {
            Topic.new {
                title = "從前從前有碗" + listOf("海龜湯", "孟婆湯", "玉米湯", "南瓜湯").random()
                description = "$title......\n$title......"
                completed = false
                tags = ""
                createdAt = DateTime.now()
                updatedAt = DateTime.now()
            }
        }
    }

原本在 Api 產生亂數標題資料的地方,改成從資料庫讀取。

        get("/api/topics") {
            val topics = transaction {
                 Topic.all().map {
                    TopicResponse(
                            id = it.id.value,
                            name = it.title,
                            avatar = "https://imgur.com/l0swFL1.jpg",
                            attendance = (0..10).random().toString() + "人"
                    )
                }
            }
            call.respond(topics)
        }

結果執行後卻沒有顯示資料,檢查發現是 Table not found 錯誤,這時候想起來少做了一個 DB_CLOSE_DELAY 設定,沒做設定的時候每個 transaction 一執行完就會關閉連線,然後資料就被清空了。

Database.connect("jdbc:h2:mem:default;DB_CLOSE_DELAY=-1", driver = "org.h2.Driver")

新設定可以保持連線狀態,也就能達成在 Ktor 服務中止時才清空資料的目的。

https://ithelp.ithome.com.tw/upload/images/20200920/20129197Yl3ZDtrW2N.png

雖然今天的進度就 App 的角度來看沒有變化,但是對 server 來說,建立、查詢題目 Api 的重要基礎已經打好,很快就能和 App 真實互動。

本次鐵人賽的作品在放進更多內容後已經成書,書名是《老姐要用Kotlin寫專案:從 Server 到 Android APP 的開發生存日記》,歡迎購買唷。https://www.tenlong.com.tw/products/9789864348978


上一篇
美美畫面的第十天:把函式當參數 OnRecyclerItemClickListener
下一篇
互相分享的第十二天:前後端都用 Kotlin 的好處
系列文
老姐好像要用 Kotlin 寫專案,能撐30天嗎?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言